﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FSM_Framework.StateMachine
{
    public class AutoTransitionListener<TOperation, TState> where TState : IEquatable<TState>
    {
        StateMachine<TOperation, TState> _stateMachine;
        public AutoTransitionListener(StateMachine<TOperation, TState> stateMachine)
        {
            _stateMachine = stateMachine;
            StartTransListening();
        }




        private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
        private Task _autoTransitionListener;
        internal async Task StartTransListening()
        {
            // if (ConditionTransTable.ContainsKey(currentState) == false) return;

            _cancellationTokenSource?.Cancel();
            if (_autoTransitionListener != null)
            {
                try
                {
                    await _autoTransitionListener;
                }
                catch
                {
                }
            }
            _cancellationTokenSource = new CancellationTokenSource();

            var token = _cancellationTokenSource.Token;


            _autoTransitionListener = await Task.Factory.StartNew(async () =>
            {
                while (true)
                {
                    Thread.Sleep(1000);
                    var currentState = _stateMachine.State;
                    if (_stateMachine.StateTransTables.ContainsKey(currentState) == false) continue;
                    if (token.IsCancellationRequested) return;
                    if (_stateMachine.IsBusy || currentState.Equals(_stateMachine.State) == false)
                    {
                        continue;
                    }

                    var conditions = _stateMachine.StateTransTables[currentState].AutoTransitions;
                    foreach (var condition in conditions)
                    {
                        var exe = condition.TransitionAction;
                        var res = await _stateMachine.ExecuteAsyncInternal(() => condition.TransitionAction.CanExecute != null, () => condition.NextBladeState, exe);
                        if (res)
                        {
                            Console.WriteLine("迁移成功，退出监听");
                            break;
                        }
                    }


                }

            }, TaskCreationOptions.LongRunning);


        }
    }
}
